﻿using System;
using System.Collections.Generic;
#if DEBUG
using System.Diagnostics;
#endif // #if DEBUG
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using FRL.DebtChased.Extensions;
using FRL.DebtChased.Silverlight.Extensions;
using FRL.DebtChased.Repository;
using FRL.DebtChased.RichContentService;

#if AGENTEDITOR
using FRL.DebtChased.AgentEditor;
#endif // #if AGENTEDITOR

#if CLIENTEDITOR
using FRL.DebtChased.ClientEditor;
#endif // #if CLIENTEDITOR


namespace FRL.DebtChased.Silverlight.Controls
{

	/// <summary>
	/// Declaration of ContactTabCtrl class
	/// </summary>
	public partial class ContactTabCtrl : UserControl
	{

		/////////////////////////////////////////////////////////////
		// Delegates and events

		public event EventHandler ContactListChange;

		/////////////////////////////////////////////////////////////
		// Constants

		private const string NewContactHeading = "*New*";

		/////////////////////////////////////////////////////////////
		// Attributes

		private bool m_bShowUserAccount = true;
		public bool ShowUserAccount
		{
			get { return m_bShowUserAccount; }
			set { m_bShowUserAccount = value; }
		}

		private bool m_bShowDOB = false;
		public bool ShowDOB
		{
			get { return m_bShowDOB; }
			set { m_bShowDOB = value; }
		}

		private Definitions.eContactType m_contactType;
		public Definitions.eContactType ContactType
		{
			get { return m_contactType; }
			set { m_contactType = value; }
		}

		private Dictionary<int, string> m_contactMap = new Dictionary<int, string>();
		public Dictionary<int, string> ContactMap
		{
			get { return m_contactMap; }
			set { m_contactMap = value; }
		}

		/////////////////////////////////////////////////////////////
		// Construction

		public ContactTabCtrl()
		{

			// Load xaml resources
			InitializeComponent();

		}

		/////////////////////////////////////////////////////////////
		// Event Handlers

		void ContactCtrl_ContentChanged(object sender, ChildCtrlContentChangeEventArg e)
		{

			// Find the tab item
			TabItem tabItem = (sender as FrameworkElement).FindParent(typeof(TabItem)) as TabItem;

			// Is this a new tab
			bool bNewTab = (tabCtrl.Items.IndexOf(tabItem) == (tabCtrl.Items.Count - 1));

			// If this is the new tab...
			if (bNewTab)
			{

				// Add another new tab
				TabItem newTabItem = _addTab(true);
				_updateTabHeading(newTabItem);

			}

			// Update heading and buttons
			if ((bNewTab) || (e.UpdateTabHeading))
				_updateTabHeading(tabItem);

			// Get the contact control
			ContactCtrl contactCtrl = tabItem.Content as ContactCtrl;
			string strTabHeading = contactCtrl.ComposeTabHeading();

			// Update header buttons
			if (bNewTab)
			{

				// Update tab header
				TabHeader tabHeader = tabItem.Header as TabHeader;

				// Add to the contacts map and send event
				m_contactMap.Add(contactCtrl.ContactId, strTabHeading);
				_onContactsChange();

			}
			else if(e.UpdateTabHeading)
			{

				// Update the map and send event
				m_contactMap[contactCtrl.ContactId] = strTabHeading;
				_onContactsChange();

			}

		}

		void ctrlContact_DeleteButtonClicked(object sender, EventArgs e)
		{

			// Update the heading for the saved tab
			ContactCtrl contactCtrl = sender as ContactCtrl;
			TabItem tabItem = contactCtrl.FindParent(typeof(TabItem)) as TabItem;
			int iIndex = tabCtrl.Items.IndexOf(tabItem);

			// Remove this tab
			_removeTab(iIndex);

			// Remove from the contacts map and send event
			m_contactMap.Remove(contactCtrl.ContactId);
			_onContactsChange();

		}

		/////////////////////////////////////////////////////////////
		// Operations

		public void _onContactsChange()
		{

			// Send message
			if (ContactListChange != null)
				ContactListChange(ContactMap, new EventArgs());

		}

		public void Set(List<ContactTransport> contacts, bool bReloading)
		{

			// Declaration of local variables
			int i1 = 0;

			// Reset the contact map
			m_contactMap.Clear();

			// Firstly, add the new tab
			if (tabCtrl.Items.Count == 0)
			{
				TabItem tabItem = _addTab(true);
				_updateTabHeading(tabItem);
			}

			// If need to create contacts...
			if (tabCtrl.Items.Count < (contacts.Count + 1))
			{

				// Add contacts
				int iNewTabsAdded = contacts.Count - tabCtrl.Items.Count + 1;
				while (iNewTabsAdded > 0)
				{
					_addTab(false);
					iNewTabsAdded--;
				} // while-loop

			}
			else if ((contacts.Count + 1) < tabCtrl.Items.Count)
			{

				// Remove contacts
				int iRemoveTabs = tabCtrl.Items.Count - contacts.Count - 1;
				while (iRemoveTabs > 0)
				{
					_removeTab(tabCtrl.Items.Count-2);
					iRemoveTabs--;
				} // while-loop

			}

			// Loop through the contacts
#if DEBUG
			Debug.Assert(tabCtrl.Items.Count == (contacts.Count + 1));
#endif // #if DEBUG
			for (i1 = 0; i1 < contacts.Count; i1++)
			{

				// Get the contact control
				TabItem tabItem = tabCtrl.Items[i1] as TabItem;
				ContactCtrl contactCtrl = tabItem.Content as ContactCtrl;

				// Set controls
				contactCtrl.Set(contacts[i1], bReloading);

				// Contact if not reloading...
				if (!bReloading)
					contactCtrl.ExpandNamePanel(false);

				// Update the tab item heading
				_updateTabHeading(tabCtrl.Items[i1] as TabItem);

				// Add to contact map
				m_contactMap.Add(contacts[i1].ContactId, contactCtrl.ComposeTabHeading());

			}

			// Make sure the last contact name is expanded
			TabItem lastTabItem = tabCtrl.Items[tabCtrl.Items.Count-1] as TabItem;
			ContactCtrl lastContactCtrl = lastTabItem.Content as ContactCtrl;
			lastContactCtrl.ExpandNamePanel(true);

			// Select the first tab
			if (!bReloading)
				tabCtrl.SelectedIndex = 0;

			// Post contact changed event
			_onContactsChange();

		}

		public List<ContactTransport> Get(List<string> Errors)
		{

			// Declare return variable
			List<ContactTransport> Ftmp = new List<ContactTransport>();

			// Loop through tabs
			for(int i1=0; i1<tabCtrl.Items.Count-1; i1++ )
			{

				// Get the next contact tab
				TabItem tabItem = tabCtrl.Items[i1] as TabItem;
				ContactCtrl contactCtrl = tabItem.Content as ContactCtrl;
				ContactTransport contact = contactCtrl.Get(Errors);
				Ftmp.Add(contact);

			}

			// Return variable
			return Ftmp;

		}

		public List<ContactAddressTransport> GetAddressList(int iIgnoreContactId)
		{

			// Declare return variable
			List<ContactAddressTransport> Ftmp = new List<ContactAddressTransport>();

			// get the contact details
			List<string> Errors = new List<string>();
			List<ContactTransport> contacts = Get(Errors);
			foreach(ContactTransport contact in contacts)
			{
				if (contact.ContactId == iIgnoreContactId)
					continue;
				foreach (ContactAddressTransport address in contact.AddressList)
					Ftmp.Add(address);
			}

			// Return variable
			return Ftmp;

		}

		private TabItem _addTab(bool bNewTab)
		{
#if DEBUG
			Debug.Assert(m_contactType != Definitions.eContactType.NotSet);
#endif // #if DEBUG

			// Declare return variable
			TabItem Ftmp = null;

			// Create a new tab
			Ftmp = new TabItem();

			// Add to tab control
			if (bNewTab)
				tabCtrl.Items.Add(Ftmp);
			else
				tabCtrl.Items.Insert(tabCtrl.Items.Count - 1, Ftmp);

			// Pick a new contact id
			int iContactId = 0;
			foreach (TabItem tabItem in tabCtrl.Items)
			{
				if (tabItem == Ftmp)
					continue;
				ContactCtrl contactCtrl = tabItem.Content as ContactCtrl;
				iContactId = Math.Min(iContactId, contactCtrl.ContactId);
			}
			iContactId--;

			// Add a contact control
			ContactCtrl ctrlContact = new ContactCtrl(this, m_contactType, iContactId);
			ctrlContact.ContentChanged += new EventHandler<ChildCtrlContentChangeEventArg>(ContactCtrl_ContentChanged);
			//ctrlContact.DeleteButtonClicked += new EventHandler(ctrlContact_DeleteButtonClicked);
			Ftmp.Content = ctrlContact;

			// Add a tab header
			TabHeader tabHeader = new TabHeader();
			Ftmp.Header = tabHeader;

			// If this is the new contact...
			if (bNewTab)
				ctrlContact.ExpandNamePanel(true);

			// Return variable
			return Ftmp;

		}

		private void _removeTab(int iOffset)
		{

			// Remove tab-item from control
			tabCtrl.Items.RemoveAt(iOffset);

		}

		private void _updateTabHeading(TabItem tabItem)
		{

			// Get the control
			ContactCtrl ctrlContact = tabItem.Content as ContactCtrl;
#if DEBUG
			Debug.Assert(ctrlContact != null);
#endif // #if DEBUG

			// Compose label
			string strLabel;
			int iIndex = tabCtrl.Items.IndexOf(tabItem);
			if (iIndex == (tabCtrl.Items.Count - 1))
				strLabel = NewContactHeading;
			else
				strLabel = ctrlContact.ComposeTabHeading();

			// Set label
			(tabItem.Header as TabHeader).Label = strLabel.DotDotDot(14);

		}

		private void tabCtrl_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{

			// Get the selected tab
			ContactCtrl contactCtrl = tabCtrl.SelectedContent as ContactCtrl;
			if(contactCtrl != null)
				contactCtrl.PreDisplay();			

		}

	}

}
